/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sgsmcan.Controlador;

import com.sgsmcan.Dao.SerenoDao;
import com.sgsmcan.Dao.SerenoDaoImpl;
import com.sgsmcan.Dao.UbigeoDao;
import com.sgsmcan.Dao.UbigeoDaoImpl;
import com.sgsmcan.Entidad.Perro;
import com.sgsmcan.Entidad.Sereno;
import com.sgsmcan.Entidad.Ubigeo;
import com.sgsmcan.EntidadFiltro.SerenoFiltro;
import com.sgsmcan.Exporter.Exporter;
import com.sgsmcan.Utils.DataExporter;
import com.sgsmcan.Utils.FiltroHibernate;
import com.sgsmcan.Utils.Paginacion;
import com.sgsmcan.Utils.SetUbigeo;
import com.sgsmcan.Utils.Utilitario;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.faces.application.NavigationHandler;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import org.hibernate.criterion.DetachedCriteria;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.UploadedFile;

/**
 *
 * @author David
 */
@ManagedBean(name = "serenoBean")
@ViewScoped
public class SerenoControlador implements Serializable {

    private SerenoDao daoSereno;
    private LazyDataModel<Sereno> serenos;
    private Sereno sereno;
    private Date fechaPemitida;
    private UbigeoDao daoUbigeo;
    private Ubigeo ubi;
    private Date fecha;
    private UploadedFile file;
    private SerenoFiltro serenoFiltro;

    /*Variables para controlar el flujo de Ubigeo*/
    SetUbigeo mapaUbigeo;
    List<SelectItem> departamentos;
    List<SelectItem> provincias;
    List<SelectItem> distritos;

    String idDepartamento;
    String idProvincia;
    String idDistrito;

    @ManagedProperty("#{usuarioBean}")
    private UsuarioControlador usuarioSesion;

    public SerenoControlador() {
        sereno = new Sereno();
        daoSereno = new SerenoDaoImpl();
        daoUbigeo = new UbigeoDaoImpl();
        serenoFiltro = new SerenoFiltro();
    }

    public void initLista() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            usuarioSesion.generarModulo(7);
            serenos = new Paginacion<Sereno>(daoSereno.getSerenos());
        }
    }

    public void insertarSereno(ActionEvent evnt) {
        sereno.setFoto("si.jpg");
        if (!esValido(false)) {
            return;
        }
        try {
            sereno.setCodigoUbigeo(ubi.getId());
            sereno.setFechaNacimiento(new java.sql.Date(fecha.getTime()));
            daoSereno.insertar(sereno);
            resetAtributos();
        } catch (Exception e) {
            e.printStackTrace();
            Utilitario.enviarMensajeGlobalError("Error al insertar los datos");
            return;
        }
        Utilitario.enviarMensajeGlobalValido("Se ha ingresado correctamente");
    }

    public String irActualizar(Integer id) {
        Utilitario.putFlash("idSereno", id);
        return "updateSereno";
    }

    public void prepararEliminar(Integer id) {
        sereno.setId(id);
    }

    public void eliminarSereno(ActionEvent evnt) {
        sereno = daoSereno.getSereno(sereno.getId());
        sereno.setEstado(Boolean.FALSE);
        daoSereno.eliminar(sereno);
        Utilitario.enviarMensajeGlobalValido("Se ha eliminado correctamente");
    }

    public void initInsertar() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            init_aux();
        }
    }

    public void init_aux() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -18);
        fechaPemitida = calendar.getTime();
        //Ubigeo
        mapaUbigeo = new SetUbigeo();
        ensamblarUbigeo();
    }

    public void initUpdate() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            Object parametro = Utilitario.getFlash("idSereno");
            if (parametro == null) {
                FacesContext fc = FacesContext.getCurrentInstance();
                NavigationHandler nh = fc.getApplication().getNavigationHandler();
                nh.handleNavigation(fc, null, "/views/serenos/list.xhtml?faces-redirect=true");
                return;
            }
            Integer id = (Integer) parametro;
            sereno = daoSereno.getSereno(id);
            fecha = sereno.getFechaNacimiento();
            init_aux();
            ubi = (Ubigeo) daoUbigeo.getUbigeo(sereno.getCodigoUbigeo());
            idDepartamento = ubi.getCodigoDepartamento();
            cambiarDepartamentos();
            idProvincia = ubi.getCodigoProvincia();
            cambiarProvincias();
            idDistrito = ubi.getCodigoDistrito();
        }
    }

    public void actualizarPerro(ActionEvent event) {
        if (!esValido(true)) {
            return;
        }
        try {
            sereno.setCodigoUbigeo(ubi.getId());
            sereno.setFechaNacimiento(new java.sql.Date(fecha.getTime()));
            daoSereno.actualizar(sereno);
        } catch (Exception e) {
            Utilitario.LOG.error("Error en SerenoControlador", e);
            return;
        }
        Utilitario.enviarMensajeGlobalValido("Se ha actualizado correctamente");
    }

    public void subirFoto(FileUploadEvent event) {
        sereno = daoSereno.getSereno(sereno.getId());
        setFile(event.getFile());
        if (getFile() == null) {
            Utilitario.enviarMensajeGlobalError("Se debe seleccionar una imagen jpg/gif/png");
            return;
        }
        try {
            sereno.setFoto(sereno.getId() + "-" + sereno.getNombre() + ".jpg");
            Utilitario.TransferFile(sereno.getFoto(), getFile().getInputstream(), Utilitario.RESOURCE_BUNDLE.getString("path_imagen_perro") + "\\");
        } catch (Exception ex) {
            Utilitario.enviarMensajeGlobalError("Ha ocurrido un error al leer la imagen");
            Utilitario.LOG.error("Error en subirFoto", ex);
            ex.printStackTrace();
            return;
        }
        try {
            daoSereno.actualizar(sereno);
        } catch (Exception e) {
            Utilitario.enviarMensajeGlobalError("Ha ocurrido un error al guardar la imagen");
            e.printStackTrace();
            return;
        }
        Utilitario.enviarMensajeGlobalValido("Se ha actualizado correctamente");
    }

    public boolean esValido(boolean update) {
        if (!esNombreValido()) {
            return false;
        }
        if (!esApellidoValido()) {
            return false;
        }
        if (!esDNIValido(update)) {
            return false;
        }
        if (!esFechaNacimientoValido()) {
            return false;
        }
        if (!esUbigeoValido()) {
            return false;
        }
        if (!esDireccionValido()) {
            return false;
        }
        if (!esCorreoValido()) {
            return false;
        }
        if (!esTelefonoValido()) {
            return false;
        }
        if (!esCelularValido()) {
            return false;
        }
        return true;
    }

    public boolean esNombreValido() {
        sereno.setNombre(sereno.getNombre() == null ? sereno.getNombre() : sereno.getNombre().trim());
        if (Utilitario.esNulo(sereno.getNombre())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el nombre");
            return false;
        } else if (!Utilitario.esSoloLetras(sereno.getNombre())) {
            Utilitario.enviarMensajeGlobalError("El nombre solamente debe ser letras");
            return false;
        } else if (!Utilitario.esRangoValido(sereno.getNombre(), 60)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres del nombre es 60");
            return false;
        }
        return true;
    }

    public boolean esApellidoValido() {
        sereno.setApellido(sereno.getApellido() == null ? sereno.getApellido() : sereno.getApellido().trim());
        if (Utilitario.esNulo(sereno.getApellido())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el apellido");
            return false;
        } else if (!Utilitario.esSoloLetras(sereno.getApellido())) {
            Utilitario.enviarMensajeGlobalError("El apellido solamente debe ser letras");
            return false;
        } else if (!Utilitario.esRangoValido(sereno.getApellido(), 80)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres del apellido es 80");
            return false;
        }
        return true;
    }

    public boolean esDNIValido(boolean update) {
        if (Utilitario.esNulo(sereno.getDni())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el DNI");
            return false;
        } else if (!Utilitario.esSoloNumero(sereno.getDni())) {
            Utilitario.enviarMensajeGlobalError("El DNI debe ser numerico");
            return false;
        } else if (!Utilitario.esRangoValido(sereno.getDni(), 8, 8)) {
            Utilitario.enviarMensajeGlobalError("El DNI debe ser de 8 caracteres");
            return false;
        } else if (daoSereno.existeDni(sereno.getDni(), update)) {
            Utilitario.enviarMensajeGlobalError("El DNI ya se encuentra resgitrado");
            return false;
        }
        return true;
    }

    public boolean esCorreoValido() {
        if (Utilitario.esNulo(sereno.getCorreo())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el Correo");
            return false;
        } else if (!Utilitario.esRangoValido(sereno.getCorreo(), 100)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres del correo es 100");
            return false;
        } else if (!Utilitario.esCorreoValido(sereno.getCorreo())) {
            Utilitario.enviarMensajeGlobalError("El formato del correo es invalido");
            return false;
        }
        return true;
    }

    public boolean esDireccionValido() {
        if (Utilitario.esNulo(sereno.getDireccion())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar la dirección");
            return false;
        }
        return true;
    }

    public boolean esTelefonoValido() {
        if (sereno.getTelefono() != null) {
            if (!Utilitario.esSoloNumero(sereno.getTelefono())) {
                Utilitario.enviarMensajeGlobalError("El telefono debe ser numerico");
                return false;
            } else if (!Utilitario.esRangoValido(sereno.getTelefono(), 7, 7)) {
                Utilitario.enviarMensajeGlobalError("El telefono debe tener 7 caracteres");
                return false;
            }
        }
        return true;
    }

    public boolean esCelularValido() {
        if (sereno.getCelular() != null) {
            if (!Utilitario.esSoloNumero(sereno.getCelular())) {
                Utilitario.enviarMensajeGlobalError("El celular debe ser numerico");
                return false;
            } else if (!Utilitario.esRangoValido(sereno.getCelular(), 9, 9)) {
                Utilitario.enviarMensajeGlobalError("El Celular debe ser de 9 caracteres");
                return false;
            }
        }
        return true;
    }

    private boolean esUbigeoValido() {
        ubi = (Ubigeo) daoUbigeo.getUbigeo(idDepartamento, idProvincia, idDistrito);
        if (ubi == null) {
            Utilitario.enviarMensajeGlobalError("Los datos del Ubigeo no son correctos");
            return false;
        }
        return true;
    }

    private boolean esFechaNacimientoValido() {
        if (fecha == null) {
            Utilitario.enviarMensajeGlobalError("Ingrese la fecha de Nacimiento");
            return false;
        } else if (fecha.after(fechaPemitida)) {
            Utilitario.enviarMensajeGlobalError("Debe tener como minimo 18 años");
            return false;
        }
        return true;
    }

    public void resetAtributos() {
        sereno = new Sereno();
        fecha = null;
        idDepartamento = null;
        idDistrito = null;
        idProvincia = null;
    }

    private void ensamblarUbigeo() {
        departamentos = new ArrayList<SelectItem>();
        provincias = new ArrayList<SelectItem>();
        distritos = new ArrayList<SelectItem>();
        List<Ubigeo> ubigeos = daoUbigeo.getUbigeos();
        for (Ubigeo ubige : ubigeos) {
            mapaUbigeo.addUbigeo(ubige);
        }
        departamentos = mapaUbigeo.getDepartamentos();
        provincias = mapaUbigeo.getProvincia("0");
        distritos = mapaUbigeo.getDistrito("0", "0");
    }

    public void cambiarDepartamentos() {
        provincias = mapaUbigeo.getProvincia(idDepartamento);
        distritos = mapaUbigeo.getDistrito("0", "0");
    }

    public void cambiarProvincias() {
        distritos = mapaUbigeo.getDistrito(idDepartamento, idProvincia);
    }

    public void buscarFiltro(ActionEvent evnt) {
        FiltroHibernate filtro = new FiltroHibernate(daoSereno.getSerenos());
        filtro.addLikeNullParametro(serenoFiltro.getNombre(), "sereno.nombre");
        filtro.addLikeNullParametro(serenoFiltro.getApellido(), "sereno.apellido");
        DetachedCriteria criteria = filtro.executeFiltro();
        serenos = new Paginacion<Sereno>(criteria);
    }
    
    public void limpiarFiltro(ActionEvent evnt) {
        serenos = new Paginacion<Sereno>(daoSereno.getSerenos());
        serenoFiltro = new SerenoFiltro();
    }

    public void exportar(ActionEvent event) {
        Paginacion<Sereno> paginacion = (Paginacion<Sereno>) serenos;
        List<Sereno> lista = paginacion.getAllList();
        if (lista.isEmpty()) {
            return;
        }
        Exporter exporter = lista.get(0);
        DataExporter<Sereno> dataExporter = new DataExporter<Sereno>(exporter);
        dataExporter.crearDocumento(lista);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        externalContext = DataExporter.getResponseContent(externalContext, "serenos");
        try {
            OutputStream outputStream = externalContext.getResponseOutputStream();
            dataExporter.exportarDocumento(outputStream);
            externalContext.setResponseStatus(200);
            externalContext.responseFlushBuffer();
            facesContext.responseComplete();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /* GETTER AND SETTER */
    public LazyDataModel<Sereno> getSerenos() {
        return serenos;
    }

    public void setSerenos(LazyDataModel<Sereno> serenos) {
        this.serenos = serenos;
    }

    public SerenoDao getDaoSereno() {
        return daoSereno;
    }

    public void setDaoSereno(SerenoDao daoSereno) {
        this.daoSereno = daoSereno;
    }

    public Sereno getSereno() {
        return sereno;
    }

    public void setSereno(Sereno sereno) {
        this.sereno = sereno;
    }

    public Date getFechaPemitida() {
        return fechaPemitida;
    }

    public void setFechaPemitida(Date fechaPemitida) {
        this.fechaPemitida = fechaPemitida;
    }

    public List<SelectItem> getDepartamentos() {
        return departamentos;
    }

    public void setDepartamentos(List<SelectItem> departamentos) {
        this.departamentos = departamentos;
    }

    public List<SelectItem> getProvincias() {
        return provincias;
    }

    public void setProvincias(List<SelectItem> provincias) {
        this.provincias = provincias;
    }

    public List<SelectItem> getDistritos() {
        return distritos;
    }

    public void setDistritos(List<SelectItem> distritos) {
        this.distritos = distritos;
    }

    public String getIdDepartamento() {
        return idDepartamento;
    }

    public void setIdDepartamento(String idDepartamento) {
        this.idDepartamento = idDepartamento;
    }

    public String getIdProvincia() {
        return idProvincia;
    }

    public void setIdProvincia(String idProvincia) {
        this.idProvincia = idProvincia;
    }

    public String getIdDistrito() {
        return idDistrito;
    }

    public void setIdDistrito(String idDistrito) {
        this.idDistrito = idDistrito;
    }

    public Date getFecha() {
        return fecha;
    }

    public void setFecha(Date fecha) {
        this.fecha = fecha;
    }

    public void setUsuarioSesion(UsuarioControlador usuarioSesion) {
        this.usuarioSesion = usuarioSesion;
    }

    public UploadedFile getFile() {
        return file;
    }

    public void setFile(UploadedFile file) {
        this.file = file;
    }

    public SerenoFiltro getSerenoFiltro() {
        return serenoFiltro;
    }

    public void setSerenoFiltro(SerenoFiltro serenoFiltro) {
        this.serenoFiltro = serenoFiltro;
    }
}
